package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.context.ModelDeploymentContext;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.FlowFileHandleService;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.ModelDeploymentPostProcessor;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowModelFileResourceHandleVo;
import lombok.extern.slf4j.Slf4j;
import org.flowable.editor.language.json.converter.BpmnJsonConverterUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
　　* @description: 保存模型所带的附件信息
　　* @author shenrm
　　* @date 2021/11/25 17:06
　　*/
@Slf4j
@Component
public class SaveModelFileInfosProcessor implements ModelDeploymentPostProcessor {

    @Autowired
    private FlowFileHandleService flowFileHandleService;

    @Override
    public void process(ModelDeploymentContext context) {
        saveAttachInfos(context.getDeployId(), context.getModelJson());
    }

    /**
     * 保存附件信息
     *
     * @param deployId
     * @param modelJson
     */
    private void saveAttachInfos(String deployId, JsonNode modelJson) {
        // 存放流程模型配置全局和节点附件信息集合
        List<FlowModelFileResourceHandleVo> handleVos = new ArrayList<>();
        // 获取流程模型节点属性
        ObjectNode properties = (ObjectNode) modelJson.get("properties");
        // 获取模型全局的附件信息
        JsonNode modelAttachInfosNode = properties.get("attachInfos");
        // 组装流程模型全局附件信息
        this.convertFileResourceHandleVoList(deployId, null, modelAttachInfosNode, handleVos);
        // 任务节点
        if (modelJson != null && modelJson.get("childShapes") != null) {
            Iterator childShapes = modelJson.get("childShapes").iterator();
            JsonNode jsonChildNode;
            String stencilId;
            while (childShapes.hasNext()) {
                jsonChildNode = (JsonNode)childShapes.next();
                stencilId = BpmnJsonConverterUtil.getStencilId(jsonChildNode);
                // 组装任务节点
                if (Objects.equals(stencilId,"UserTask")) {
                    // 获取节点编码
                    String activityId = jsonChildNode.get("properties").get("overrideid").asText();
                    // 获取节点的附件信息
                    JsonNode activityAttachInfosNode = jsonChildNode.get("properties").get("attachInfos");
                    // 组装流程模型节点附件信息
                    this.convertFileResourceHandleVoList(deployId, activityId, activityAttachInfosNode, handleVos);
                }
            }
        }
        // 批量更新
        this.saveAttachInfos(handleVos);
    }

    /**
     * 组装全局和节点的附件信息
     *
     * @param deployId
     * @param activityId
     * @param attachInfosNode
     * @param handleVos
     */
    private void convertFileResourceHandleVoList(String deployId, String activityId,
                                                 JsonNode attachInfosNode, List<FlowModelFileResourceHandleVo> handleVos) {
        // 判断全局是否有附件信息,如果有,则处理组装,否则,则向下处理
        if(Objects.nonNull(attachInfosNode)) {
            // 循环组装全局和节点的附件信息
            ArrayNode nodeArr = (ArrayNode) attachInfosNode;
            if (Objects.nonNull(nodeArr)) {
                for (JsonNode jsonNode : nodeArr) {
                    FlowModelFileResourceHandleVo handleVo = new FlowModelFileResourceHandleVo();
                    handleVo.setDeploymentId(deployId);
                    handleVo.setActivityId(activityId);
                    handleVo.setAttachId(jsonNode.get("attachId").asText());
                    handleVo.setFileName(jsonNode.get("fileName").asText());
                    handleVo.setServiceType(jsonNode.get("serviceType").asText());
                    handleVos.add(handleVo);
                }
            }
        }
    }

    /**
     * 保存附件信息
     *
     * @param handleVos
     */
    private void saveAttachInfos(List<FlowModelFileResourceHandleVo> handleVos) {
        // 批量新增附件信息
        try {
            if(CollectionUtils.isEmpty(handleVos)) {
                return;
            }
            flowFileHandleService.batchInsertFileResourceHandleRel(handleVos);
        }catch (Exception e) {
            log.error("批量保存模型或节点与附件关系时失败,失败原因：" + e.getMessage(), e);
        }
    }
}
